package com.school.sports.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.school.sports.entity.CertificateRecord;
import com.school.sports.entity.CertificateTemplate;
import com.school.sports.service.CertificateRecordService;
import com.school.sports.service.CertificateTemplateService;
import com.school.sports.common.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * 证书管理控制器
 * 处理证书模板管理和证书生成相关请求
 */
@RestController
@RequestMapping("/api/certificate")
@CrossOrigin
public class CertificateManagementController {

    private static final Logger logger = LoggerFactory.getLogger(CertificateManagementController.class);

    @Autowired
    private CertificateTemplateService certificateTemplateService;

    @Autowired
    private CertificateRecordService certificateRecordService;

    // ========== 证书模板管理 ==========

    /**
     * 分页查询证书模板
     * @param currentPage 当前页码
     * @param pageSize 每页显示数量
     * @param template 查询条件
     * @return 分页结果
     */
    @GetMapping("/template/page/{currentPage}/{pageSize}")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<IPage<CertificateTemplate>> getTemplatePage(
            @PathVariable("currentPage") Integer currentPage,
            @PathVariable("pageSize") Integer pageSize,
            CertificateTemplate template) {

        logger.info("分页查询证书模板，当前页码：{}，每页条数：{}", currentPage, pageSize);

        try {
            IPage<CertificateTemplate> page = certificateTemplateService.getPage(currentPage, pageSize, template);
            logger.info("查询证书模板成功，共{}条记录", page.getTotal());
            return Result.success(page);
        } catch (Exception e) {
            logger.error("查询证书模板失败：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 根据类型获取模板列表
     * @param templateType 模板类型
     * @return 模板列表
     */
    @GetMapping("/template/type/{templateType}")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<List<CertificateTemplate>> getTemplatesByType(@PathVariable("templateType") String templateType) {
        logger.info("根据类型查询证书模板：{}", templateType);

        try {
            List<CertificateTemplate> templates = certificateTemplateService.getTemplatesByType(templateType);
            logger.info("查询到{}个{}类型模板", templates.size(), templateType);
            return Result.success(templates);
        } catch (Exception e) {
            logger.error("查询证书模板失败：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 创建证书模板
     * @param template 模板信息
     * @return 创建结果
     */
    @PostMapping("/template")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<String> createTemplate(@RequestBody CertificateTemplate template) {
        logger.info("创建证书模板：{}", template.getTemplateName());

        try {
            Long currentUserId = getCurrentUserId();
            boolean result = certificateTemplateService.createTemplate(template, currentUserId);
            if (result) {
                logger.info("证书模板创建成功：{}", template.getTemplateName());
                return Result.success("创建成功");
            } else {
                logger.warn("证书模板创建失败：{}", template.getTemplateName());
                return Result.fail("创建失败");
            }
        } catch (Exception e) {
            logger.error("创建证书模板失败：{}", e.getMessage(), e);
            return Result.fail("创建失败：" + e.getMessage());
        }
    }

    /**
     * 更新证书模板
     * @param template 模板信息
     * @return 更新结果
     */
    @PutMapping("/template")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<String> updateTemplate(@RequestBody CertificateTemplate template) {
        logger.info("更新证书模板，ID：{}", template.getId());

        try {
            boolean result = certificateTemplateService.updateTemplate(template);
            if (result) {
                logger.info("证书模板更新成功，ID：{}", template.getId());
                return Result.success("更新成功");
            } else {
                logger.warn("证书模板更新失败，ID：{}", template.getId());
                return Result.fail("更新失败");
            }
        } catch (Exception e) {
            logger.error("更新证书模板失败：{}", e.getMessage(), e);
            return Result.fail("更新失败：" + e.getMessage());
        }
    }

    /**
     * 设置默认模板
     * @param templateId 模板ID
     * @param templateType 模板类型
     * @return 设置结果
     */
    @PutMapping("/template/{templateId}/default")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<String> setAsDefault(
            @PathVariable("templateId") Long templateId,
            @RequestParam("templateType") String templateType) {

        logger.info("设置默认模板，ID：{}，类型：{}", templateId, templateType);

        try {
            boolean result = certificateTemplateService.setAsDefault(templateId, templateType);
            if (result) {
                logger.info("设置默认模板成功，ID：{}", templateId);
                return Result.success("设置成功");
            } else {
                logger.warn("设置默认模板失败，ID：{}", templateId);
                return Result.fail("设置失败");
            }
        } catch (Exception e) {
            logger.error("设置默认模板失败：{}", e.getMessage(), e);
            return Result.fail("设置失败：" + e.getMessage());
        }
    }

    /**
     * 删除证书模板
     * @param templateId 模板ID
     * @return 删除结果
     */
    @DeleteMapping("/template/{templateId}")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<String> deleteTemplate(@PathVariable("templateId") Long templateId) {
        logger.info("删除证书模板，ID：{}", templateId);

        try {
            boolean result = certificateTemplateService.deleteTemplate(templateId);
            if (result) {
                logger.info("证书模板删除成功，ID：{}", templateId);
                return Result.success("删除成功");
            } else {
                logger.warn("证书模板删除失败，ID：{}", templateId);
                return Result.fail("删除失败");
            }
        } catch (Exception e) {
            logger.error("删除证书模板失败：{}", e.getMessage(), e);
            return Result.fail("删除失败：" + e.getMessage());
        }
    }

    // ========== 证书生成管理 ==========

    /**
     * 分页查询证书记录
     * @param currentPage 当前页码
     * @param pageSize 每页显示数量
     * @param record 查询条件
     * @return 分页结果
     */
    @GetMapping("/record/page/{currentPage}/{pageSize}")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<IPage<CertificateRecord>> getRecordPage(
            @PathVariable("currentPage") Integer currentPage,
            @PathVariable("pageSize") Integer pageSize,
            CertificateRecord record) {

        logger.info("分页查询证书记录，当前页码：{}，每页条数：{}", currentPage, pageSize);

        try {
            IPage<CertificateRecord> page = certificateRecordService.getPage(currentPage, pageSize, record);
            logger.info("查询证书记录成功，共{}条记录", page.getTotal());
            return Result.success(page);
        } catch (Exception e) {
            logger.error("查询证书记录失败：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 生成参赛证书
     * @param userId 用户ID
     * @param projectId 项目ID
     * @return 生成结果
     */
    @PostMapping("/generate/participation")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<CertificateRecord> generateParticipationCertificate(
            @RequestParam("userId") Long userId,
            @RequestParam("projectId") Long projectId) {

        logger.info("生成参赛证书，用户ID：{}，项目ID：{}", userId, projectId);

        try {
            Long currentUserId = getCurrentUserId();
            CertificateRecord record = certificateRecordService.generateParticipationCertificate(userId, projectId, currentUserId);
            logger.info("参赛证书生成成功，证书编号：{}", record.getCertificateNo());
            return Result.success(record);
        } catch (Exception e) {
            logger.error("生成参赛证书失败：{}", e.getMessage(), e);
            return Result.fail("生成失败：" + e.getMessage());
        }
    }

    /**
     * 生成获奖证书
     * @param userId 用户ID
     * @param projectId 项目ID
     * @param awardId 奖项ID
     * @param awardLevel 奖项等级
     * @return 生成结果
     */
    @PostMapping("/generate/award")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<CertificateRecord> generateAwardCertificate(
            @RequestParam("userId") Long userId,
            @RequestParam("projectId") Long projectId,
            @RequestParam("awardId") Long awardId,
            @RequestParam("awardLevel") String awardLevel) {

        logger.info("生成获奖证书，用户ID：{}，项目ID：{}，奖项ID：{}，奖项等级：{}",
                userId, projectId, awardId, awardLevel);

        try {
            Long currentUserId = getCurrentUserId();
            CertificateRecord record = certificateRecordService.generateAwardCertificate(
                    userId, projectId, awardId, awardLevel, currentUserId);
            logger.info("获奖证书生成成功，证书编号：{}", record.getCertificateNo());
            return Result.success(record);
        } catch (Exception e) {
            logger.error("生成获奖证书失败：{}", e.getMessage(), e);
            return Result.fail("生成失败：" + e.getMessage());
        }
    }

    /**
     * 生成志愿者证书
     * @param userId 用户ID
     * @return 生成结果
     */
    @PostMapping("/generate/volunteer")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<CertificateRecord> generateVolunteerCertificate(@RequestParam("userId") Long userId) {
        logger.info("生成志愿者证书，用户ID：{}", userId);

        try {
            Long currentUserId = getCurrentUserId();
            CertificateRecord record = certificateRecordService.generateVolunteerCertificate(userId, currentUserId);
            logger.info("志愿者证书生成成功，证书编号：{}", record.getCertificateNo());
            return Result.success(record);
        } catch (Exception e) {
            logger.error("生成志愿者证书失败：{}", e.getMessage(), e);
            return Result.fail("生成失败：" + e.getMessage());
        }
    }

    /**
     * 生成裁判证书
     * @param userId 用户ID
     * @return 生成结果
     */
    @PostMapping("/generate/referee")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<CertificateRecord> generateRefereeCertificate(@RequestParam("userId") Long userId) {
        logger.info("生成裁判证书，用户ID：{}", userId);

        try {
            Long currentUserId = getCurrentUserId();
            CertificateRecord record = certificateRecordService.generateRefereeCertificate(userId, currentUserId);
            logger.info("裁判证书生成成功，证书编号：{}", record.getCertificateNo());
            return Result.success(record);
        } catch (Exception e) {
            logger.error("生成裁判证书失败：{}", e.getMessage(), e);
            return Result.fail("生成失败：" + e.getMessage());
        }
    }

    /**
     * 批量生成证书
     * @param userIds 用户ID列表
     * @param certificateType 证书类型
     * @param projectId 项目ID（可选）
     * @param awardId 奖项ID（可选）
     * @param awardLevel 奖项等级（可选）
     * @return 生成结果
     */
    @PostMapping("/generate/batch")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<List<CertificateRecord>> batchGenerateCertificates(
            @RequestParam("userIds") List<Long> userIds,
            @RequestParam("certificateType") String certificateType,
            @RequestParam(value = "projectId", required = false) Long projectId,
            @RequestParam(value = "awardId", required = false) Long awardId,
            @RequestParam(value = "awardLevel", required = false) String awardLevel) {

        logger.info("批量生成证书，用户数量：{}，证书类型：{}", userIds.size(), certificateType);

        try {
            Long currentUserId = getCurrentUserId();
            List<CertificateRecord> records = certificateRecordService.batchGenerateCertificates(
                    userIds, certificateType, projectId, awardId, awardLevel, currentUserId);
            logger.info("批量生成证书成功，生成{}个证书", records.size());
            return Result.success(records);
        } catch (Exception e) {
            logger.error("批量生成证书失败：{}", e.getMessage(), e);
            return Result.fail("批量生成失败：" + e.getMessage());
        }
    }

    /**
     * 重新生成证书
     * @param certificateId 证书ID
     * @return 生成结果
     */
    @PostMapping("/regenerate/{certificateId}")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<CertificateRecord> regenerateCertificate(@PathVariable("certificateId") Long certificateId) {
        logger.info("重新生成证书，ID：{}", certificateId);

        try {
            Long currentUserId = getCurrentUserId();
            CertificateRecord record = certificateRecordService.regenerateCertificate(certificateId, currentUserId);
            logger.info("证书重新生成成功，新证书编号：{}", record.getCertificateNo());
            return Result.success(record);
        } catch (Exception e) {
            logger.error("重新生成证书失败：{}", e.getMessage(), e);
            return Result.fail("重新生成失败：" + e.getMessage());
        }
    }

    /**
     * 撤销证书
     * @param certificateId 证书ID
     * @return 撤销结果
     */
    @PutMapping("/revoke/{certificateId}")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<String> revokeCertificate(@PathVariable("certificateId") Long certificateId) {
        logger.info("撤销证书，ID：{}", certificateId);

        try {
            boolean result = certificateRecordService.revokeCertificate(certificateId);
            if (result) {
                logger.info("证书撤销成功，ID：{}", certificateId);
                return Result.success("撤销成功");
            } else {
                logger.warn("证书撤销失败，ID：{}", certificateId);
                return Result.fail("撤销失败");
            }
        } catch (Exception e) {
            logger.error("撤销证书失败：{}", e.getMessage(), e);
            return Result.fail("撤销失败：" + e.getMessage());
        }
    }

    /**
     * 下载证书
     * @param certificateId 证书ID
     * @param response HTTP响应对象
     */
    @GetMapping("/download/{certificateId}")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER', 'STUDENT', 'REFEREE', 'VOLUNTEER')")
    public void downloadCertificate(@PathVariable("certificateId") Long certificateId, HttpServletResponse response) {
        logger.info("下载证书，ID：{}", certificateId);

        try {
            CertificateRecord record = certificateRecordService.getById(certificateId);
            if (record == null) {
                response.setStatus(HttpStatus.NOT_FOUND.value());
                return;
            }

            // 设置响应头
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment; filename=\"certificate_" + record.getCertificateNo() + ".pdf\"");

            // 这里应该读取实际的证书文件内容并写入响应流
            // 简化处理，实际实现应该从文件系统或云存储读取

            logger.info("证书下载成功，ID：{}", certificateId);
        } catch (Exception e) {
            logger.error("下载证书失败：{}", e.getMessage(), e);
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

    /**
     * 验证证书
     * @param certificateNo 证书编号
     * @return 验证结果
     */
    @GetMapping("/validate/{certificateNo}")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER', 'STUDENT', 'REFEREE', 'VOLUNTEER')")
    public Result<Map<String, Object>> validateCertificate(@PathVariable("certificateNo") String certificateNo) {
        logger.info("验证证书，编号：{}", certificateNo);

        try {
            boolean isValid = certificateRecordService.validateCertificate(certificateNo);
            CertificateRecord record = certificateRecordService.getCertificateByNo(certificateNo);

            Map<String, Object> result = new java.util.HashMap<>();
            result.put("valid", isValid);
            if (isValid && record != null) {
                result.put("certificateInfo", record);
            }

            return Result.success(result);
        } catch (Exception e) {
            logger.error("验证证书失败：{}", e.getMessage(), e);
            return Result.fail("验证失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户证书列表
     * @param userId 用户ID（可选）
     * @return 证书列表
     */
    @GetMapping("/user/{userId}")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER', 'STUDENT', 'REFEREE', 'VOLUNTEER')")
    public Result<List<CertificateRecord>> getUserCertificates(@PathVariable(value = "userId", required = false) Long userId) {
        try {
            if (userId == null) {
                userId = getCurrentUserId();
            }

            List<CertificateRecord> certificates = certificateRecordService.getCertificatesByUserId(userId);
            logger.info("查询到用户{}的{}个证书", userId, certificates.size());
            return Result.success(certificates);
        } catch (Exception e) {
            logger.error("查询用户证书失败：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 获取证书统计信息
     * @return 统计信息
     */
    @GetMapping("/statistics")
    @PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
    public Result<List<CertificateRecord>> getCertificateStatistics() {
        try {
            List<CertificateRecord> statistics = certificateRecordService.getCertificateStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取证书统计信息失败：{}", e.getMessage(), e);
            return Result.fail("获取统计信息失败：" + e.getMessage());
        }
    }

    // ========== 私有辅助方法 ==========

    /**
     * 获取当前用户ID（简化实现）
     */
    private Long getCurrentUserId() {
        // 实际应该从SecurityContext获取当前用户信息
        // 这里返回1作为示例
        return 1L;
    }
}